{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "array([0.73105858, 0.88079708, 0.95257413])"
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'''\n",
    "math包里只能传入实数，numpy可以传入矩阵和向量\n",
    "'''\n",
    "import numpy as np\n",
    "def sigmoid(x):\n",
    "    s = 1 / (1 + np.exp(-x))\n",
    "    return s\n",
    "x = np.array([1, 2, 3])\n",
    "sigmoid(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构造sigmoid函数的导数\n",
    "对Sigmoid函数求导得:\n",
    "$sigmoid\\_derivative(x) = \\sigma'(x) = \\sigma(x) (1 - \\sigma(x))\\tag{2}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sigmoid_derivative(x) = [0.19661193 0.10499359 0.04517666]\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "构造ds（sigmoid函数的导数）\n",
    "'''\n",
    "def sigmoid_derivative(x):\n",
    "    s = sigmoid(x)\n",
    "    ds = s * (1 - s)\n",
    "    return ds\n",
    "x = np.array([1, 2, 3])\n",
    "print (\"sigmoid_derivative(x) = \" + str(sigmoid_derivative(x)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数组/矩阵/向量重塑 reshape()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "image2vector(image) = [[0.67826139]\n",
      " [0.29380381]\n",
      " [0.90714982]\n",
      " [0.52835647]\n",
      " [0.4215251 ]\n",
      " [0.45017551]\n",
      " [0.92814219]\n",
      " [0.96677647]\n",
      " [0.85304703]\n",
      " [0.52351845]\n",
      " [0.19981397]\n",
      " [0.27417313]\n",
      " [0.60659855]\n",
      " [0.00533165]\n",
      " [0.10820313]\n",
      " [0.49978937]\n",
      " [0.34144279]\n",
      " [0.94630077]]\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "重塑数组\n",
    "-X.shape用于获取矩阵/向量X的shape（维度）\n",
    "-X.reshape（...）用于将X重塑为其他尺寸\n",
    "下列函数将图像重塑为向量\n",
    "'''\n",
    "def image2vector(image):\n",
    "    \"\"\"\n",
    "    Argument:\n",
    "    image -- a numpy array of shape (length, height, depth)\n",
    "    \n",
    "    Returns:\n",
    "    v -- a vector of shape (length*height*depth, 1)\n",
    "    \"\"\"\n",
    "    v = image.reshape(image.shape[0] * image.shape[1] * image.shape[2], 1)\n",
    "    return v\n",
    "'''\n",
    "image是一个3*3*2的向量\n",
    "'''\n",
    "image = np.array([[[ 0.67826139,  0.29380381],\n",
    "        [ 0.90714982,  0.52835647],\n",
    "        [ 0.4215251 ,  0.45017551]],\n",
    "\n",
    "       [[ 0.92814219,  0.96677647],\n",
    "        [ 0.85304703,  0.52351845],\n",
    "        [ 0.19981397,  0.27417313]],\n",
    "\n",
    "       [[ 0.60659855,  0.00533165],\n",
    "        [ 0.10820313,  0.49978937],\n",
    "        [ 0.34144279,  0.94630077]]])\n",
    "print (\"image2vector(image) = \" + str(image2vector(image)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 归一化  $\\frac{x}{\\| x\\|}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "normalizeRows(x) = [[0.         0.6        0.8       ]\n",
      " [0.13736056 0.82416338 0.54944226]]\n"
     ]
    }
   ],
   "source": [
    "def normalizeRows(x):\n",
    "    x_norm = np.linalg.norm(x, axis = 1, keepdims = True)\n",
    "    '''\n",
    "    np.linalg.norm用于求范数，ord=2或ord缺省时为二范数\n",
    "    '''\n",
    "    x = x / x_norm\n",
    "    return x\n",
    "x = np.array([\n",
    "    [0, 3, 4],\n",
    "    [1, 6, 4]])\n",
    "print(\"normalizeRows(x) = \" + str(normalizeRows(x)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 广播及其在Softmax中的应用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "softmax(x) = [[9.80897665e-01 8.94462891e-04 1.79657674e-02 1.21052389e-04\n",
      "  1.21052389e-04]\n",
      " [8.78679856e-01 1.18916387e-01 8.01252314e-04 8.01252314e-04\n",
      "  8.01252314e-04]]\n"
     ]
    }
   ],
   "source": [
    "def softmax(x):\n",
    "    x_exp = np.exp(x)\n",
    "    x_sum = np.sum(x_exp, axis = 1, keepdims = True)\n",
    "    s = x_exp / x_sum\n",
    "    '''\n",
    "    这里x_exp是矩阵，x_sum是实数，在计算时用到了广播\n",
    "    '''\n",
    "    return s\n",
    "x = np.array([\n",
    "    [9, 2, 5, 0, 0],\n",
    "    [7, 5, 0, 0 ,0]])\n",
    "print(\"softmax(x) = \" + str(softmax(x)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 实现L1和L2损失函数\n",
    "L1损失函数：$\\begin{align*} & L_1(\\hat{y}, y) = \\sum_{i=0}^m|y^{(i)} - \\hat{y}^{(i)}| \\end{align*}\\tag{6}$\n",
    "L2损失函数：$\\begin{align*} & L_2(\\hat{y},y) = \\sum_{i=0}^m(y^{(i)} - \\hat{y}^{(i)})^2 \\end{align*}\\tag{7}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'''\n",
    "L1损失函数\n",
    "'''\n",
    "def L1(yhat, y):\n",
    "    loss = np.sum(np.abs(y - yhat))\n",
    "    return loss\n",
    "'''\n",
    "L2损失函数\n",
    "'''\n",
    "def L2(yhat, y):\n",
    "    loss = np.dot((y - yhat),(y - yhat).T)\n",
    "    '''\n",
    "    \n",
    "    '''\n",
    "    return loss"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}